package org.infodavid.common.persistence;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import junit.framework.Assert;

import org.junit.Test;

import org.infodavid.common.impl.model.criteria.ApplicationSettingsCriteriaImpl;
import org.infodavid.common.impl.model.criteria.GenericPropertyCriteriaImpl;
import org.infodavid.common.model.ApplicationSettingsTest;
import org.infodavid.common.model.IApplicationSettings;
import org.infodavid.common.model.IGenericProperty;
import org.infodavid.common.model.criteria.IApplicationSettingsCriteria;
import org.infodavid.common.model.criteria.IGenericPropertyCriteria;

/**
 * The Class ApplicationSettingsDataServiceTest.
 */
@SuppressWarnings({
	"null"
})
public class ApplicationSettingsDataServiceTest extends
    AbstractDataServiceTest<IApplicationSettings,IApplicationSettings,Long> {

	/**
	 * The Constructor.
	 */
	public ApplicationSettingsDataServiceTest() {
		super(new ApplicationSettingsTest(), ApplicationSettingsDataService.getInstance());
	}

	/*
	 * See super class or interface. (non-Javadoc)
	 * @see
	 * org.infodavid.common.persistence.AbstractDataServiceTest#modify(org.infodavid.common.model.IDataObject
	 * )
	 */
	@Override
	public void modify(final IApplicationSettings item) {
		item.setProduct(item.getProduct() + "modified-" + System.nanoTime());
	}

	/**
	 * Test get instance.
	 */
	@Test
	public final void testGetInstance() {
		Assert.assertEquals("Not a singleton", ApplicationSettingsDataService.getInstance(),
		    ApplicationSettingsDataService.getInstance());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteria() throws Exception {
		final List<IApplicationSettings> results = new ArrayList<IApplicationSettings>();
		final IApplicationSettingsCriteria criteria = new ApplicationSettingsCriteriaImpl();
		final long count =
		    ((ApplicationSettingsDataService)getService()).find(getSession(), results, criteria);

		//System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, results.size());
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingAllCriterions() throws Exception {
		final Collection<IApplicationSettings> inserted = getTestData();
		final List<IApplicationSettings> results = new ArrayList<IApplicationSettings>();
		final IApplicationSettingsCriteria criteria = new ApplicationSettingsCriteriaImpl();

		criteria.setProductNamePattern(inserted.iterator().next().getProduct());

		final long count =
		    ((ApplicationSettingsDataService)getService()).find(getSession(), results, criteria);

		//System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", 1, results.size());
		Assert.assertEquals("Not all data has been found", 1, count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingNameNoDataFound() throws Exception {
		final List<IApplicationSettings> results = new ArrayList<IApplicationSettings>();
		final IApplicationSettingsCriteria criteria = new ApplicationSettingsCriteriaImpl();

		criteria.setProductNamePattern("NoData");

		final long count =
		    ((ApplicationSettingsDataService)getService()).find(getSession(), results, criteria);

		//System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", 0, results.size());
		Assert.assertEquals("Not all data has been found", 0, count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingNameEqual() throws Exception {
		final Collection<IApplicationSettings> inserted = getTestData();
		final List<IApplicationSettings> results = new ArrayList<IApplicationSettings>();
		final IApplicationSettingsCriteria criteria = new ApplicationSettingsCriteriaImpl();

		criteria.setProductNamePattern(inserted.iterator().next().getProduct());

		final long count =
		    ((ApplicationSettingsDataService)getService()).find(getSession(), results, criteria);

		//System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", 1, results.size());
		Assert.assertEquals("Not all data has been found", 1, count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingNameLike() throws Exception {
		final List<IApplicationSettings> results = new ArrayList<IApplicationSettings>();
		final IApplicationSettingsCriteria criteria = new ApplicationSettingsCriteriaImpl();

		criteria.setProductNamePattern("item%");

		final long count =
		    ((ApplicationSettingsDataService)getService()).find(getSession(), results, criteria);

		//System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, results.size());
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingNullCollection() throws Exception {
		final IApplicationSettingsCriteria criteria = new ApplicationSettingsCriteriaImpl();
		Exception exception = null;

		try {
			((ApplicationSettingsDataService)getService()).find(getSession(), null, criteria);
		}
		catch (final Exception e) {
			exception = e;
			e.printStackTrace();
		}

		Assert.assertNotNull("No exception thrown", exception);
		Assert.assertEquals("Wrong exception thrown", IllegalArgumentException.class,
		    exception.getClass());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingNullCriteria() throws Exception {
		final List<IApplicationSettings> results = new ArrayList<IApplicationSettings>();
		final long count =
		    ((ApplicationSettingsDataService)getService()).find(getSession(), results,
		        (IApplicationSettingsCriteria)null);

		//System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, results.size());
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByCriteriaUsingPage() throws Exception {
		final List<IApplicationSettings> results = new ArrayList<IApplicationSettings>();
		final IApplicationSettingsCriteria criteria = new ApplicationSettingsCriteriaImpl();

		criteria.setPageStart(Long.valueOf(0));
		criteria.setPageSize(Integer.valueOf(5));

		final long count =
		    ((ApplicationSettingsDataService)getService()).find(getSession(), results, criteria);

		//System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", criteria.getPageSize().intValue(),
		    results.size());
		Assert.assertEquals("Not all data has been found", ITEMS_TO_INSERT, count);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByName() throws Exception {
		final Collection<IApplicationSettings> inserted = getTestData();
		final IApplicationSettings result =
		    ((ApplicationSettingsDataService)getService()).findByProduct(getSession(), inserted
		        .iterator().next().getProduct());

		Assert.assertNotNull("Result is null", result);
		Assert.assertEquals("Wrong data found", inserted.iterator().next().getProduct(),
		    result.getProduct());
		Assert.assertEquals("Wrong data found", inserted.iterator().next().getKey(), result.getKey());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindByNameUsingNull() throws Exception {
		Exception exception = null;

		try {
			((ApplicationSettingsDataService)getService()).findByProduct(getSession(), null);
		}
		catch (final Exception e) {
			exception = e;
			e.printStackTrace();
		}

		Assert.assertNull("Exception thrown", exception);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindNotNullPropertyValue() throws Exception {
		final List<IApplicationSettings> inserted = getTestData();
		final IApplicationSettings entity = inserted.get(0);
		final IGenericProperty prop = entity.getProperties().getData().iterator().next();
		final String result =
		    ((ApplicationSettingsDataService)getService()).findNotNullPropertyValue(getSession(),
		        prop.getName());

		Assert.assertNotNull("Result is null", result);
		Assert.assertEquals("Wrong data found", prop.getValue(), result);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindNotNullPropertyValueUsingNull() throws Exception {
		Exception exception = null;

		try {
			((ApplicationSettingsDataService)getService()).findNotNullPropertyValue(getSession(), null);
		}
		catch (final Exception e) {
			exception = e;
			e.printStackTrace();
		}

		Assert.assertNull("Exception thrown", exception);
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindPropertiesByCriteria() throws Exception {
		final List<IApplicationSettings> inserted = getTestData();
		final List<IGenericProperty> results = new ArrayList<IGenericProperty>();
		final IGenericPropertyCriteria criteria = new GenericPropertyCriteriaImpl();
		final IApplicationSettings entity = inserted.get(0);

		((ApplicationSettingsDataService)getService()).findProperties(getSession(), results,
		    entity.getProduct(), criteria);

		//System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", entity.getProperties().size(),
		    results.size());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindPropertiesByCriteriaUsingNameEqual() throws Exception {
		final List<IApplicationSettings> inserted = getTestData();
		final List<IGenericProperty> results = new ArrayList<IGenericProperty>();
		final IGenericPropertyCriteria criteria = new GenericPropertyCriteriaImpl();
		final IApplicationSettings entity = inserted.get(0);
		final IGenericProperty prop = entity.getProperties().getData().iterator().next();

		criteria.setNamePattern(prop.getName());

		((ApplicationSettingsDataService)getService()).findProperties(getSession(), results,
		    entity.getProduct(), criteria);

		//System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", 1, results.size());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindPropertiesByCriteriaUsingNameLike() throws Exception {
		final List<IApplicationSettings> inserted = getTestData();
		final List<IGenericProperty> results = new ArrayList<IGenericProperty>();
		final IGenericPropertyCriteria criteria = new GenericPropertyCriteriaImpl();
		final IApplicationSettings entity = inserted.get(0);
		final IGenericProperty prop = entity.getProperties().getData().iterator().next();

		criteria.setNamePattern(prop.getName() + "%");

		((ApplicationSettingsDataService)getService()).findProperties(getSession(), results,
		    entity.getProduct(), criteria);

		//System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertTrue("Not all data has been found", 1 <= results.size());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindPropertiesByCriteriaUsingNameNoDataFound() throws Exception {
		final List<IApplicationSettings> inserted = getTestData();
		final List<IGenericProperty> results = new ArrayList<IGenericProperty>();
		final IGenericPropertyCriteria criteria = new GenericPropertyCriteriaImpl();
		final IApplicationSettings entity = inserted.get(0);

		criteria.setNamePattern("NoData");

		((ApplicationSettingsDataService)getService()).findProperties(getSession(), results,
		    entity.getProduct(), criteria);

		//System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertEquals("Not all data has been found", 0, results.size());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindPropertiesByCriteriaUsingNullCollection() throws Exception {
		final List<IApplicationSettings> inserted = getTestData();
		final IGenericPropertyCriteria criteria = new GenericPropertyCriteriaImpl();
		final IApplicationSettings entity = inserted.get(0);
		Exception exception = null;

		try {
			((ApplicationSettingsDataService)getService()).findProperties(getSession(), null,
			    entity.getProduct(), criteria);
		}
		catch (final Exception e) {
			exception = e;
			e.printStackTrace();
		}

		Assert.assertNotNull("No exception thrown", exception);
		Assert.assertEquals("Wrong exception thrown", IllegalArgumentException.class,
		    exception.getClass());
	}

	/**
	 * Test find.
	 * @throws Exception the exception
	 */
	@Test
	public void testFindPropertiesByCriteriaUsingNullCriteria() throws Exception {
		final List<IApplicationSettings> inserted = getTestData();
		final List<IGenericProperty> results = new ArrayList<IGenericProperty>();
		final IApplicationSettings entity = inserted.get(0);

		((ApplicationSettingsDataService)getService()).findProperties(getSession(), results,
		    entity.getProduct(), (IGenericPropertyCriteria)null);

		//System.out.println(results);

		Assert.assertNotNull("Result is null", results);
		Assert.assertTrue("Not all data has been found", 1 < results.size());
	}
}
